package com.wxzhou.wangzhuan.repository;

import com.wxzhou.wangzhuan.entity.WzButie;
import com.wxzhou.wangzhuan.entity.WzButieRecord;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.sqlclient.Pool;
import io.vertx.mutiny.sqlclient.Row;
import io.vertx.mutiny.sqlclient.Tuple;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.jboss.logging.Logger;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 补贴持久化对象
 */
@ApplicationScoped
public class ButieRespository {

    private static final Logger LOG = Logger.getLogger(ButieRespository.class);

    @Inject
    Pool client;

    /**
     * 根据一批查询用户的补贴。
     *
     * @param userid
     * @param senses
     * @return
     */
    public Uni<List<WzButie>> findAllButieBy(Long userid, List<Integer> senses) {
        String placeholders = senses.stream()
                .map(id -> "$" + (senses.indexOf(id) + 2)) // 占位符从 $2 开始
                .collect(Collectors.joining(","));

        String sql = "select distinct a.* from wz_butie a  where a.user_id = $1 AND a.sense in (" + placeholders + ")";
        List<Object> tuples = new ArrayList<>();
        tuples.add(userid);
        tuples.addAll(senses);

        return client.preparedQuery(sql).execute(Tuple.from(tuples)).onItem().transform(rows -> {
            List<WzButie> adLogs = new ArrayList<>();
            for (Row row : rows) {
                adLogs.add(mapRowToWzButie(row));
            }
            return adLogs;
        }).onFailure().invoke(throwable -> throwable.printStackTrace());
    }

    /**
     * 批量插入补贴数据
     *
     * @param wzButies
     * @return
     */
    public Uni<Integer> batchInsertButieRecord(List<WzButieRecord> wzButies, String transId) {
        if (wzButies == null || wzButies.isEmpty()) {
            return Uni.createFrom().item(0);
        }

        // 安全检查：确保批量大小在合理范围内
        final int MAX_BATCH_SIZE = 2000; // 最大批量大小
        if (wzButies.size() > MAX_BATCH_SIZE) {
            LOG.warnf("wz_butie_record", "批量数量过大，建议分批处理",
                    "requestedSize=" + wzButies.size() + ", maxBatchSize=" + MAX_BATCH_SIZE);
            // 这里可以选择抛出异常或者继续处理，为了兼容性选择继续处理
        }

        // 计算SQL参数数量：每条7个字段
        final int FIELDS_PER_COMMENT = 7;
        final int totalParams = wzButies.size() * FIELDS_PER_COMMENT;

        // 安全检查：确保参数数量在合理范围内
        final int MAX_PARAMS = 50000; // 最大参数数量限制
        if (totalParams > MAX_PARAMS) {
            LOG.errorf("wz_butie_record", "批量参数数量过多，可能导致性能问题",
                    "totalParams=" + totalParams + ", maxParams=" + MAX_PARAMS +
                            ", commentCount=" + wzButies.size());
            return Uni.createFrom().failure(new IllegalArgumentException(
                    "批量参数数量过多: " + totalParams + " > " + MAX_PARAMS));
        }


        List<String> insertColumns = Arrays.asList("butie_id", "amount", "trans_id", "user_id", "sense", "butie_type", "day_max_amount", "day_amount_left", "day_amount_right", "start_at", "end_at");

        // 列名拼接
        String columns = String.join(", ", insertColumns);

        // 动态生成占位符（$1, $2, $3...）
        List<String> placeholderList = new ArrayList<>();
        //批量构造插入语句
        int tempindex = 0;
        List tuples = new ArrayList();
        for (int i = 0; i < wzButies.size(); i++) {
            WzButieRecord wzButie = wzButies.get(i);
            List<String> tempPlaceholderList = new ArrayList<>();
            for (int j = 0; j < insertColumns.size(); j++) {
                //i=1 ，insertColumns.size()+i开始
                tempindex = j + 1 + i * insertColumns.size();
                tempPlaceholderList.add("$" + tempindex);
            }
            List<? extends Serializable> list = Arrays.asList(wzButie.getButieId(), wzButie.getAmount(), transId, wzButie.getUserId(), wzButie.getSense(), wzButie.getButie_type(), wzButie.getDay_max_amount(), wzButie.getDay_amount_left(),
                    wzButie.getDay_amount_right(), wzButie.getStart_at(), wzButie.getEnd_at());
            tuples.addAll(list);
            String format = String.join(", ", tempPlaceholderList);
            String format1 = String.format("(%s)", format);
            placeholderList.add(format1);
        }

        String placeholders = String.join(", ", placeholderList);

        String sql = String.format(
                "INSERT INTO wz_butie_record (%s) VALUES %s ",
                columns,
                placeholders
        );

        return client.preparedQuery(sql.toString())
                .execute(Tuple.from(tuples))
                .onItem().transform(rows -> {
                    int rowCount = rows.rowCount();
                    LOG.infof("wz_butie", "批量操作成功", "count=" + rowCount);
                    return rowCount;
                })
                .onFailure().recoverWithUni(throwable -> {
                    LOG.errorf(throwable, "批量插入补贴失败");
                    return Uni.createFrom().item(0);
                });
    }

    private WzButie mapRowToWzButie(Row row) {
        WzButie config = new WzButie();
        config.setId(row.getLong("id"));
        config.setUserId(row.getLong("user_id"));
        config.setSense(row.getInteger("sense"));
        config.setButie_type(row.getInteger("butie_type"));
        config.setDay_max_amount(row.getBigDecimal("day_max_amount"));
        config.setDay_amount_left(row.getBigDecimal("day_amount_left"));
        config.setDay_amount_right(row.getBigDecimal("day_amount_right"));
        config.setStart_at(row.getLocalDateTime("start_at"));
        config.setEnd_at(row.getLocalDateTime("end_at"));
        config.setCreatedAt(row.getLocalDateTime("created_at"));
        config.setRemark(row.getString("remark"));
        return config;
    }

}
